--
-- VHDL Architecture Fietscomputer_lib.rom2lcd.v1
--
-- Created:
--          by - jcmooije.UNKNOWN (dtp7985)
--          at - 15:57:30  9-07-2010
--
-- using Mentor Graphics HDL Designer(TM) 2007.1 (Build 19)
--
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_arith.all;
USE ieee.std_logic_unsigned.all;

ENTITY fc_rom2lcd IS
   GENERIC( 
      nrow : NATURAL := 8 
   );
   PORT( 
      row_req       : IN     STD_LOGIC_VECTOR (nrow-1 DOWNTO 0) := (OTHERS => '0');
      clk           : IN     STD_LOGIC;
      rst           : IN     STD_LOGIC;
      BCD           : IN     STD_LOGIC_VECTOR (31 DOWNTO 0);
      bin2BCD_ready : IN     STD_LOGIC;
      inp_select    : OUT    STD_LOGIC_VECTOR (2 DOWNTO 0);
      conv_time     : OUT    STD_LOGIC;
      start_bin2BCD : OUT    STD_LOGIC;
      LCD_DATA      : OUT    STD_LOGIC_VECTOR (7 DOWNTO 0);
      LCD_RW        : OUT    STD_LOGIC;
      LCD_EN        : OUT    STD_LOGIC;
      LCD_RS        : OUT    STD_LOGIC;
      LCD_ON        : OUT    STD_LOGIC
   );

-- Declarations

END fc_rom2lcd ;
  
  --------------------------------------------------------------------
  ------------------------------------------------------------------------
  
  
ARCHITECTURE v1 OF fc_rom2lcd IS
  
  CONSTANT nclm : NATURAL := 21;
  
  SIGNAL row_req_reg :  STD_LOGIC_VECTOR (nrow-1 DOWNTO 0);
  
  TYPE ROM_TABLE IS ARRAY (0 TO nrow * nclm - 1 ) OF CHARACTER;
  
  CONSTANT ROM : ROM_TABLE := ROM_TABLE'(

  "   0 Current Speed:  " & -- 0
  "A  1     21.0 km/h  >" & -- 1
  "   0 Total length:   " & -- 2
  "A  1 <  654321.0 km  " & -- 3
  "   0 Exit mainmenu   " & -- 4
  "   0 Trips           " & -- 5
  "   0 Bicycledata     " & -- 6
  "   1  <<   select  >>" & -- 7
  "   1       select  >>" & -- 8
  "   1  <<   select    " & -- 9
  "   0 Loading...      " & -- 10
  "   0 Exit trip menu  " & -- 11
  "   0 Start trip      " & -- 12
  "   0 Trip data       " & -- 13
  "   0 End trip        " & -- 14
  "   0 Average speed:  " & -- 15
  "A  1    21.0 km/h   >" & -- 16
  "   0 Trip length:    " & -- 17
  "A  1 <  4321.0 km   >" & -- 18
  "   0 Trip time:      " & -- 19
  "A T1 <   54:32:10    " & -- 20
  "   0 Serialnumber:   " & -- 21
  "B  1 76543210        "   -- 22
  );
  
 
  
  
  SIGNAL timer     : NATURAL RANGE 0 TO 400;
  
  
  TYPE statetype IS (Power_On, Function_Set, Display_On_Off, Clear_Display, Entry_Mode_Set, Initialization_End, sddram, Wait4Bin2BCD, chr2lcd);
  SIGNAL state : statetype;
  
  
  
  SIGNAL ROM_row   : NATURAL RANGE 0 TO nrow-1;
  SIGNAL ROM_clm   : NATURAL RANGE 0 TO nclm-1;
  SIGNAL LCD_row   : NATURAL RANGE 1 TO 2;
  
  BEGIN
    
    
    
    HH:  
    PROCESS(rst, clk)
      
      VARIABLE chr : CHARACTER; 
      VARIABLE ci  : INTEGER RANGE 0 TO 63; 
      
      BEGIN
        IF rst = '1' THEN
          
          row_req_reg    <= (OTHERS => '0');
          row_req_reg(0) <= '0';
          row_req_reg(1) <= '0';
          
          timer          <= 0;
          
          
                    conv_time <= '0';
          
          ROM_row        <=  0;
          ROM_clm        <=  0;
			 
          inp_select     <= (OTHERS => '0');
          start_bin2bcd  <= '0'; 
          
          
          
          state          <=  Power_On; 
          
          
          
          
          LCD_RS         <= '0';
          LCD_DATA       <= "00000000";
          LCD_EN         <= '0';
          LCD_ON         <= '0';
          
        ELSIF RISING_EDGE(clk) THEN
          
          row_req_reg    <= row_req_reg  OR row_req;
          
          
          
          IF state /= Power_On AND timer = 1 THEN
            LCD_EN   <= '1';
          ELSE 
            LCD_EN   <= '0';
          END IF;
          
          
          CASE state IS
            
          WHEN Power_On     => 
            LCD_ON         <= '1';
            
            IF timer >= 400 THEN   -- 400
              timer  <= 0;
              state <= Function_Set;
            ELSE 
               timer <= timer + 1;
            END IF;
            
            
            
          WHEN Function_Set  => 
            
            LCD_RS <= '0';
            LCD_DATA <= "00111000";  -- "00111000"; DL N F
            
            IF timer = 2 THEN
              timer  <= 0;
              state <= Display_On_Off;
            ELSE
              timer <= timer + 1;
            END IF;
            
          WHEN  Display_On_Off  => 
            
            LCD_DATA <= "00001100";
            LCD_RS <= '0';
            
            
            IF timer = 2 THEN
              timer <= 0;
              state <= Clear_Display;
            ELSE
            timer <= timer + 1; 
            END IF; 
            
            
            
          WHEN  Clear_Display  => 
            
            LCD_DATA <= "00000001";
            LCD_RS <= '0';
            
            
            
            IF timer= 20 THEN
              timer <= 0;
              state <= Entry_Mode_Set;
            ELSE
              timer <= timer + 1; 
            END IF;
            
            
            
            
          WHEN  Entry_Mode_Set  => 
            
            LCD_DATA <= "00000110";   --   10  I/D  SH
            LCD_RS <= '0';
            
            IF timer = 2 THEN
              timer <= 0;
              state <= Initialization_End;
            ELSE
               timer <= timer + 1;  
            END IF;
            
            
          WHEN Initialization_End =>
            
            LCD_RS   <= '0';
            
            
            IF row_req_reg(rom_row) = '1' THEN
              timer <= 0;
              row_req_reg(rom_row) <= '0';
              state <= sddram;
            ELSIF rom_row = nrow - 1 THEN
              rom_row <= 0;
            ELSE
              rom_row <= rom_row + 1;
            END IF;
            
            
          WHEN sddram =>
            
            
            chr := ROM(rom_row * nclm); 
            inp_select <= CONV_STD_LOGIC_VECTOR(CHARACTER'POS(chr),3);
            
            IF ROM(rom_row * nclm + 2) = 'T' THEN
              conv_time <= '1';
            ELSE
              conv_time <= '0';
            END IF;
            
            IF ROM(rom_row * nclm + 3) = '0' THEN
              LCD_DATA <= "10000000"; -- First LCD row
            ELSE
              LCD_DATA <= "11000000"; -- Second LCD row
            END IF; 
            
            ROM_clm <= 5;
            
            IF timer = 2 THEN
              timer <= 0;
              IF chr = ' ' THEN
                state <= chr2lcd;
              ELSE
                start_bin2bcd <= '1'; 
                state <= Wait4Bin2BCD;
              END IF;
            ELSE
              timer <= timer + 1;
            END IF;  
            
            
            
            
          WHEN  Wait4Bin2BCD =>
            
            start_bin2bcd <= '0'; 
            IF bin2BCD_ready = '1' THEN
              state <= chr2lcd;
            END IF;
            
            
            
          WHEN chr2lcd =>
            
            chr := ROM(rom_row * nclm + ROM_clm); 
            
            
            
            CASE chr IS
            WHEN '0' =>  LCD_DATA <= x"30" + BCD( 3 DOWNTO  0);
            WHEN '1' =>  LCD_DATA <= x"30" + BCD( 7 DOWNTO  4);
            WHEN '2' =>  LCD_DATA <= x"30" + BCD(11 DOWNTO  8);
            WHEN '3' =>  LCD_DATA <= x"30" + BCD(15 DOWNTO 12);
            WHEN '4' =>  LCD_DATA <= x"30" + BCD(19 DOWNTO 16);
            WHEN '5' =>  LCD_DATA <= x"30" + BCD(23 DOWNTO 20);
            WHEN '6' =>  LCD_DATA <= x"30" + BCD(27 DOWNTO 24);
            WHEN '7' =>  LCD_DATA <= x"30" + BCD(31 DOWNTO 28);
            WHEN '_' =>  LCD_DATA <= x"20"; 
            WHEN OTHERS =>  LCD_DATA <= CONV_STD_LOGIC_VECTOR(CHARACTER'POS(chr),8);
            END CASE;
            
            LCD_RS <= '1';
            
            
            IF timer = 2 THEN
              timer <= 0;
              IF ROM_clm = nclm - 1 THEN
                
                IF rom_row = nrow - 1 THEN
                  rom_row <= 0;
                ELSE
                  rom_row <= rom_row + 1;
                END IF;  
                state <= Initialization_End;
                
              ELSE
                ROM_clm <= ROM_clm  + 1;
                IF chr = '_' THEN
                  chr := ROM(rom_row * nclm + 1); 
                  inp_select <= CONV_STD_LOGIC_VECTOR(CHARACTER'POS(chr),3);
                  start_bin2bcd <= '1'; 
                  state <= Wait4Bin2BCD;
                ELSE
                  state <= chr2lcd;
                END IF;
              END IF;
            ELSE
              timer <= timer + 1;
            END IF;
            
            
            
          END CASE;
          
        END IF;
      END PROCESS;
      
           
      
      
      LCD_RW <= '0';
      
   
      
    END ARCHITECTURE v1;
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
